home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1995 June
/
MacFormat 25.iso
/
Shareware City
/
Developers
/
OutOfPhase1.1 Source
/
OutOfPhase Folder
/
WaveTableWindow.c
< prev
next >
Wrap
Text File
|
1994-12-28
|
75KB
|
2,436 lines
/* WaveTableWindow.c */
/*****************************************************************************/
/* */
/* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
/* Copyright (C) 1994 Thomas R. Lawrence */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
/* */
/*****************************************************************************/
#include "MiscInfo.h"
#include "Audit.h"
#include "Debug.h"
#include "Definitions.h"
#include "WaveTableWindow.h"
#include "MainWindowStuff.h"
#include "CodeCenter.h"
#include "WaveTableList.h"
#include "TextEdit.h"
#include "IconButton.h"
#include "Scroll.h"
#include "SimpleButton.h"
#include "SampleView.h"
#include "WindowDispatcher.h"
#include "WaveTableObject.h"
#include "Memory.h"
#include "Numbers.h"
#include "Array.h"
#include "DataMunging.h"
#include "EditImages.h"
#include "GrowIcon.h"
#include "Main.h"
#include "StringDialog.h"
#include "FindDialog.h"
#include "GlobalWindowMenuList.h"
#include "WaveTableStorage.h"
#include "WaveTableStorageDisplay.h"
#include "SoundOutput.h"
#include "Alert.h"
#include "NumberDialog.h"
#include "WaveTableSizeDialog.h"
#include "CompilerRoot.h"
#include "PcodeObject.h"
#include "PcodeStack.h"
#include "PcodeSystem.h"
#include "FunctionCode.h"
#define PAGEINCREMENT (1)
#define EIGHTBITSHIFTFACTOR (18)
#define SIXTEENBITSHIFTFACTOR (10)
#define WINDOWXSIZE (420)
#define WINDOWYSIZE (300)
#define NAMEEDITX (80)
#define NAMEEDITY (1)
#define NAMEEDITWIDTH (80)
#define NAMEEDITHEIGHT (19)
#define NAMEX (3)
#define NAMEY (NAMEEDITY + 3)
#define FRAMEEDITX (NAMEEDITX)
#define FRAMEEDITY (NAMEEDITY + NAMEEDITHEIGHT + 3)
#define FRAMEEDITWIDTH (NAMEEDITWIDTH)
#define FRAMEEDITHEIGHT (NAMEEDITHEIGHT)
#define FRAMEX (NAMEX)
#define FRAMEY (FRAMEEDITY + 3)
#define TABLESEDITX (FRAMEEDITX)
#define TABLESEDITY (FRAMEEDITY + FRAMEEDITHEIGHT + 3)
#define TABLESEDITWIDTH (FRAMEEDITWIDTH)
#define TABLESEDITHEIGHT (FRAMEEDITHEIGHT)
#define TABLESX (FRAMEX)
#define TABLESY (TABLESEDITY + 3)
#define BITS8BUTTONX (10)
#define BITS8BUTTONY (TABLESEDITY + TABLESEDITHEIGHT + 5)
#define BITS8BUTTONWIDTH (32)
#define BITS8BUTTONHEIGHT (32)
#define BITS16BUTTONX (BITS8BUTTONX + BITS8BUTTONWIDTH + 1)
#define BITS16BUTTONY (BITS8BUTTONY)
#define BITS16BUTTONWIDTH (BITS8BUTTONWIDTH)
#define BITS16BUTTONHEIGHT (BITS8BUTTONHEIGHT)
#define TESTATTACKDURATIONX (TABLESEDITX)
#define TESTATTACKDURATIONY (BITS16BUTTONY + BITS16BUTTONHEIGHT + 5)
#define TESTATTACKDURATIONWIDTH (TABLESEDITWIDTH)
#define TESTATTACKDURATIONHEIGHT (TABLESEDITHEIGHT)
#define TESTATTACKX (TABLESX)
#define TESTATTACKY (TESTATTACKDURATIONY + 3)
#define TESTDECAYDURATIONX (TESTATTACKDURATIONX)
#define TESTDECAYDURATIONY (TESTATTACKDURATIONY + TESTATTACKDURATIONHEIGHT + 3)
#define TESTDECAYDURATIONWIDTH (TESTATTACKDURATIONWIDTH)
#define TESTDECAYDURATIONHEIGHT (TESTATTACKDURATIONHEIGHT)
#define TESTDECAYX (TESTATTACKX)
#define TESTDECAYY (TESTDECAYDURATIONY + 3)
#define TESTFREQUENCYX (TESTDECAYDURATIONX)
#define TESTFREQUENCYY (TESTDECAYDURATIONY + TESTDECAYDURATIONHEIGHT + 3)
#define TESTFREQUENCYWIDTH (TESTDECAYDURATIONWIDTH)
#define TESTFREQUENCYHEIGHT (TESTDECAYDURATIONHEIGHT)
#define TESTFREQX (TESTDECAYX)
#define TESTFREQY (TESTFREQUENCYY + 3)
#define TESTSAMPLINGRATEX (TESTFREQUENCYX)
#define TESTSAMPLINGRATEY (TESTFREQUENCYY + TESTFREQUENCYHEIGHT + 3)
#define TESTSAMPLINGRATEWIDTH (TESTFREQUENCYWIDTH)
#define TESTSAMPLINGRATEHEIGHT (TESTFREQUENCYHEIGHT)
#define TESTSAMPLX (TESTFREQX)
#define TESTSAMPLY (TESTSAMPLINGRATEY + 3)
#define TESTBUTTONX (10)
#define TESTBUTTONY (TESTSAMPLINGRATEY + TESTSAMPLINGRATEHEIGHT + 5)
#define TESTBUTTONWIDTH (80)
#define TESTBUTTONHEIGHT (21)
#define EXPRESSIONEDITX (-1)
#define EXPRESSIONEDITWIDTH(WindowWidth) ((WindowWidth) + 2)
#define EXPRESSIONEDITHEIGHT (80)
#define EXPRESSIONEDITY(WindowHeight) ((WindowHeight) - EXPRESSIONEDITHEIGHT + 1)
#define WAVEFORMVIEWX (NAMEEDITX + NAMEEDITWIDTH + 10)
#define WAVEFORMVIEWY (-1)
#define WAVEFORMVIEWWIDTH(WinWidth) ((WinWidth) - WAVEFORMVIEWX + 1)
#define WAVEFORMVIEWHEIGHT(WinHeight) (EXPRESSIONEDITY(WinHeight) - WAVEFORMVIEWY - 16)
#define TABLESCROLLY(WinHeight) (WAVEFORMVIEWY + WAVEFORMVIEWHEIGHT(WinHeight) - 1)
struct WaveTableWindowRec
{
MainWindowRec* MainWindow;
CodeCenterRec* CodeCenter;
WaveTableListRec* WaveTableList;
WaveTableObjectRec* WaveTableObject;
WaveTableStorDispRec* WaveTableData;
MyBoolean WaveDataModified;
WaveTableStorDispRec* UndoBackupWaveTable;
WinType* ScreenID;
TextEditRec* NameEdit;
TextEditRec* FunctionEdit;
TextEditRec* NumFramesEdit;
TextEditRec* NumTablesEdit;
TextEditRec* TestAttackDuration;
TextEditRec* TestDecayDuration;
TextEditRec* TestFrequency;
TextEditRec* TestSamplingRate;
TextEditRec* ActiveTextEdit;
SimpleButtonRec* TestButton;
IconButtonRec* Bits8Button;
IconButtonRec* Bits16Button;
ScrollRec* TableScroll;
long CurrentlyVisibleTable;
GenericWindowRec* MyGenericWindow; /* how the window event dispatcher knows us */
MenuItemType* MyMenuItem;
};
/* create a new wave table window. */
WaveTableWindowRec* NewWaveTableWindow(struct MainWindowRec* MainWindow,
struct WaveTableObjectRec* WaveTableObject,
struct CodeCenterRec* CodeCenter,
struct WaveTableListRec* WaveTableList,
struct WaveTableStorageRec* WaveData,
OrdType WinX, OrdType WinY, OrdType WinWidth, OrdType WinHeight)
{
WaveTableWindowRec* Window;
char* StringTemp;
long Scan;
long Limit;
CheckPtrExistence(MainWindow);
CheckPtrExistence(WaveTableObject);
CheckPtrExistence(CodeCenter);
CheckPtrExistence(WaveTableList);
CheckPtrExistence(WaveData);
/* deal with window placement */
if ((WinWidth < 100) || (WinHeight < 100) || ((eOptionKey & CheckModifiers()) != 0))
{
WinX = 1 + WindowOtherEdgeWidths(eDocumentWindow);
WinY = 1 + WindowTitleBarHeight(eDocumentWindow);
WinWidth = WINDOWXSIZE;
WinHeight = WINDOWYSIZE;
}
MakeWindowFitOnScreen(&WinX,&WinY,&WinWidth,&WinHeight);
Window = (WaveTableWindowRec*)AllocPtrCanFail(sizeof(WaveTableWindowRec),
"WaveTableWindowRec");
if (Window == NIL)
{
FailurePoint1:
return NIL;
}
Window->MainWindow = MainWindow;
Window->WaveTableObject = WaveTableObject;
Window->CodeCenter = CodeCenter;
Window->WaveTableList = WaveTableList;
Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
eWindowZoomable,eWindowResizable,WinX,WinY,WinWidth,WinHeight,
(void (*)(void*))&WaveTableWindowUpdator,Window);
if (Window->ScreenID == 0)
{
FailurePoint2:
ReleasePtr((char*)Window);
goto FailurePoint1;
}
Window->NameEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,NAMEEDITX,NAMEEDITY,NAMEEDITWIDTH,NAMEEDITHEIGHT);
if (Window->NameEdit == NIL)
{
FailurePoint3:
KillWindow(Window->ScreenID);
goto FailurePoint2;
}
StringTemp = WaveTableObjectGetNameCopy(WaveTableObject);
if (StringTemp == NIL)
{
FailurePoint4:
DisposeTextEdit(Window->NameEdit);
goto FailurePoint3;
}
TextEditNewRawData(Window->NameEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->NameEdit);
Window->FunctionEdit = NewTextEdit(Window->ScreenID,
(TEScrollType)(eTEVScrollBar | eTEHScrollBar),GetMonospacedFont(),9,
EXPRESSIONEDITX,EXPRESSIONEDITY(WinHeight),EXPRESSIONEDITWIDTH(WinWidth),
EXPRESSIONEDITHEIGHT);
if (Window->FunctionEdit == NIL)
{
FailurePoint5:
goto FailurePoint4;
}
StringTemp = WaveTableObjectGetFormulaCopy(WaveTableObject);
SetTextEditTabSize(Window->FunctionEdit,MainWindowGetTabSize(MainWindow));
if (StringTemp == NIL)
{
FailurePoint6:
DisposeTextEdit(Window->FunctionEdit);
goto FailurePoint5;
}
TextEditNewRawData(Window->FunctionEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->FunctionEdit);
SetTextEditAutoIndent(Window->FunctionEdit,True);
Window->NumFramesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,FRAMEEDITX,FRAMEEDITY,FRAMEEDITWIDTH,FRAMEEDITHEIGHT);
if (Window->NumFramesEdit == NIL)
{
FailurePoint7:
goto FailurePoint6;
}
StringTemp = IntegerToString(WaveTableObjectEntriesPerTable(WaveTableObject));
if (StringTemp == NIL)
{
FailurePoint8:
DisposeTextEdit(Window->NumFramesEdit);
goto FailurePoint7;
}
TextEditNewRawData(Window->NumFramesEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->NumFramesEdit);
Window->NumTablesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,TABLESEDITX,TABLESEDITY,TABLESEDITWIDTH,TABLESEDITHEIGHT);
if (Window->NumTablesEdit == NIL)
{
FailurePoint9:
goto FailurePoint8;
}
StringTemp = IntegerToString(WaveTableObjectGetNumTables(WaveTableObject));
if (StringTemp == NIL)
{
FailurePoint10:
DisposeTextEdit(Window->NumTablesEdit);
goto FailurePoint9;
}
TextEditNewRawData(Window->NumTablesEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->NumTablesEdit);
Window->TestAttackDuration = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,TESTATTACKDURATIONX,TESTATTACKDURATIONY,TESTATTACKDURATIONWIDTH,
TESTATTACKDURATIONHEIGHT);
if (Window->TestAttackDuration == NIL)
{
FailurePoint11:
goto FailurePoint10;
}
StringTemp = LongDoubleToString(WaveTableObjectGetTestAttack(WaveTableObject),
6,1e-4,1e6);
if (StringTemp == NIL)
{
FailurePoint12:
DisposeTextEdit(Window->TestAttackDuration);
goto FailurePoint11;
}
TextEditNewRawData(Window->TestAttackDuration,StringTemp,"\x0a");
ReleasePtr(StringTemp);
Window->TestDecayDuration = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,TESTDECAYDURATIONX,TESTDECAYDURATIONY,TESTDECAYDURATIONWIDTH,
TESTDECAYDURATIONHEIGHT);
if (Window->TestDecayDuration == NIL)
{
FailurePoint13:
goto FailurePoint12;
}
StringTemp = LongDoubleToString(WaveTableObjectGetTestDecay(WaveTableObject),
6,1e-4,1e6);
if (StringTemp == NIL)
{
FailurePoint14:
DisposeTextEdit(Window->TestDecayDuration);
goto FailurePoint13;
}
TextEditNewRawData(Window->TestDecayDuration,StringTemp,"\x0a");
ReleasePtr(StringTemp);
Window->Bits8Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS8BUTTONX,
BITS8BUTTONY,BITS8BUTTONWIDTH,BITS8BUTTONHEIGHT,Bits8Unselected,Bits8MouseDown,
Bits8Selected,Bits8Selected,eIconRadioMode);
if (Window->Bits8Button == NIL)
{
FailurePoint15:
goto FailurePoint14;
}
Window->Bits16Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS16BUTTONX,
BITS16BUTTONY,BITS16BUTTONWIDTH,BITS16BUTTONHEIGHT,Bits16Unselected,
Bits16MouseDown,Bits16Selected,Bits16Selected,eIconRadioMode);
if (Window->Bits16Button == NIL)
{
FailurePoint16:
DisposeIconButton(Window->Bits8Button);
goto FailurePoint15;
}
switch (WaveTableObjectGetNumBits(WaveTableObject))
{
default:
EXECUTE(PRERR(ForceAbort,"NewWaveTableWindow: bad number of bits"));
break;
case eSample8bit:
SetIconButtonState(Window->Bits8Button,True);
break;
case eSample16bit:
SetIconButtonState(Window->Bits16Button,True);
break;
}
Window->TestButton = NewSimpleButton(Window->ScreenID,"Test",
TESTBUTTONX,TESTBUTTONY,TESTBUTTONWIDTH,TESTBUTTONHEIGHT);
if (Window->TestButton == NIL)
{
FailurePoint17:
DisposeIconButton(Window->Bits16Button);
goto FailurePoint16;
}
Window->TableScroll = NewScrollBar(Window->ScreenID,eHScrollBar,
WAVEFORMVIEWX,TABLESCROLLY(WinHeight),WAVEFORMVIEWWIDTH(WinWidth));
if (Window->TableScroll == NIL)
{
FailurePoint18:
DisposeSimpleButton(Window->TestButton);
goto FailurePoint17;
}
Window->CurrentlyVisibleTable = 0;
Window->WaveTableData = NewWaveTableStorDisp(WaveTableStorageNumBits(WaveData),
WaveTableStorageNumFramesPerTable(WaveData));
if (Window->WaveTableData == NIL)
{
FailurePoint19:
DisposeScrollBar(Window->TableScroll);
goto FailurePoint18;
}
Limit = WaveTableStorageNumTables(WaveData);
for (Scan = 0; Scan < Limit; Scan += 1)
{
long Index;
long IndexLimit;
if (!WaveTableStorDispAppendEntry(Window->WaveTableData))
{
FailurePoint20:
DisposeWaveTableStorDisp(Window->WaveTableData);
goto FailurePoint19;
}
IndexLimit = WaveTableStorageNumFramesPerTable(WaveData);
for (Index = 0; Index < IndexLimit; Index += 1)
{
WaveTableStorDispSetFrame(Window->WaveTableData,Scan,Index,
WaveTableStorageGetFrame(WaveData,Scan,Index));
}
}
Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
(void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&WaveTableWindowDoIdle,
(void (*)(void*))&WaveTableWindowBecomeActive,
(void (*)(void*))&WaveTableWindowBecomeInactive,
(void (*)(void*))&WaveTableWindowJustResized,
(void (*)(OrdType,OrdType,ModifierFlags,void*))&WaveTableWindowDoMouseDown,
(void (*)(unsigned char,ModifierFlags,void*))&WaveTableWindowDoKeyDown,
(void (*)(void*))&WaveTableWindowClose,
(void (*)(void*))&WaveTableWindowMenuSetup,
(void (*)(void*,MenuItemType*))&WaveTableWindowDoMenuCommand);
if (Window->MyGenericWindow == NIL)
{
FailurePoint21:
goto FailurePoint20;
}
Window->TestFrequency = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,TESTFREQUENCYX,TESTFREQUENCYY,TESTFREQUENCYWIDTH,
TESTFREQUENCYHEIGHT);
if (Window->TestFrequency == NIL)
{
FailurePoint22:
CheckOutDyingWindow(Window->MyGenericWindow);
goto FailurePoint21;
}
StringTemp = LongDoubleToString(WaveTableObjectGetTestPitch(WaveTableObject),
13,1e-4,1e6);
if (StringTemp == NIL)
{
FailurePoint23:
DisposeTextEdit(Window->TestFrequency);
goto FailurePoint22;
}
TextEditNewRawData(Window->TestFrequency,StringTemp,"\x0a");
ReleasePtr(StringTemp);
Window->TestSamplingRate = NewTextEdit(Window->ScreenID,eTENoScrollBars,
GetScreenFont(),9,TESTSAMPLINGRATEX,TESTSAMPLINGRATEY,TESTSAMPLINGRATEWIDTH,
TESTSAMPLINGRATEHEIGHT);
if (Window->TestSamplingRate == NIL)
{
FailurePoint24:
goto FailurePoint23;
}
StringTemp = IntegerToString(WaveTableObjectGetTestSamplingRate(WaveTableObject));
if (StringTemp == NIL)
{
FailurePoint25:
DisposeTextEdit(Window->TestSamplingRate);
goto FailurePoint24;
}
TextEditNewRawData(Window->TestSamplingRate,StringTemp,"\x0a");
ReleasePtr(StringTemp);
Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
if (Window->MyMenuItem == NIL)
{
FailurePoint26:
goto FailurePoint25;
}
if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
Window->ScreenID))
{
FailurePoint27:
KillMenuItem(Window->MyMenuItem);
goto FailurePoint26;
}
Window->WaveDataModified = False;
Window->ActiveTextEdit = Window->FunctionEdit;
Window->UndoBackupWaveTable = NIL;
WaveTableWindowResetTitlebar(Window);
WaveTableWindowUpdateScrollBar(Window);
return Window;
}
/* write back modified data and dispose of the wave table window */
void DisposeWaveTableWindow(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
/* save data */
if (!WaveTableWindowWritebackModifiedData(Window))
{
/* failed -- now what? */
}
WaveTableObjectClosingWindowNotify(Window->WaveTableObject,
GetWindowXStart(Window->ScreenID),GetWindowYStart(Window->ScreenID),
GetWindowWidth(Window->ScreenID),GetWindowHeight(Window->ScreenID));
DeregisterWindowMenuItem(Window->MyMenuItem);
KillMenuItem(Window->MyMenuItem);
CheckOutDyingWindow(Window->MyGenericWindow);
DisposeWaveTableStorDisp(Window->WaveTableData);
if (Window->UndoBackupWaveTable != NIL)
{
DisposeWaveTableStorDisp(Window->UndoBackupWaveTable);
}
DisposeScrollBar(Window->TableScroll);
DisposeIconButton(Window->Bits16Button);
DisposeIconButton(Window->Bits8Button);
DisposeTextEdit(Window->NameEdit);
DisposeTextEdit(Window->FunctionEdit);
DisposeTextEdit(Window->NumFramesEdit);
DisposeTextEdit(Window->NumTablesEdit);
DisposeTextEdit(Window->TestAttackDuration);
DisposeTextEdit(Window->TestDecayDuration);
DisposeTextEdit(Window->TestFrequency);
DisposeTextEdit(Window->TestSamplingRate);
DisposeSimpleButton(Window->TestButton);
KillWindow(Window->ScreenID);
ReleasePtr((char*)Window);
}
/* return True if the data has been modified since the last time the file was saved */
MyBoolean HasWaveTableWindowBeenModified(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
return Window->WaveDataModified
|| TextEditDoesItNeedToBeSaved(Window->NameEdit)
|| TextEditDoesItNeedToBeSaved(Window->FunctionEdit)
|| TextEditDoesItNeedToBeSaved(Window->TestAttackDuration)
|| TextEditDoesItNeedToBeSaved(Window->TestDecayDuration)
|| TextEditDoesItNeedToBeSaved(Window->TestFrequency)
|| TextEditDoesItNeedToBeSaved(Window->TestSamplingRate);
}
/* bring the window to the top and give it the focus */
void WaveTableWindowBringToTop(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
ActivateThisWindow(Window->ScreenID);
}
void WaveTableWindowDoIdle(WaveTableWindowRec* Window,
MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
ModifierFlags Modifiers)
{
CheckPtrExistence(Window);
if (Window->ActiveTextEdit != NIL)
{
TextEditUpdateCursor(Window->ActiveTextEdit);
}
if (CheckCursorFlag)
{
if (TextEditIBeamTest(Window->NameEdit,XLoc,YLoc)
|| TextEditIBeamTest(Window->FunctionEdit,XLoc,YLoc)
|| TextEditIBeamTest(Window->NumFramesEdit,XLoc,YLoc)
|| TextEditIBeamTest(Window->NumTablesEdit,XLoc,YLoc)
|| TextEditIBeamTest(Window->TestAttackDuration,XLoc,YLoc)
|| TextEditIBeamTest(Window->TestDecayDuration,XLoc,YLoc)
|| TextEditIBeamTest(Window->TestFrequency,XLoc,YLoc)
|| TextEditIBeamTest(Window->TestSamplingRate,XLoc,YLoc))
{
SetIBeamCursor();
}
else if ((XLoc >= WAVEFORMVIEWX) && (YLoc >= WAVEFORMVIEWY)
&& (XLoc < WAVEFORMVIEWX + WAVEFORMVIEWWIDTH(GetWindowWidth(Window->ScreenID)))
&& (YLoc < WAVEFORMVIEWY
+ WAVEFORMVIEWHEIGHT(GetWindowHeight(Window->ScreenID)) - 15))
{
SetSampleInsertionCursor();
}
else
{
SetArrowCursor();
}
}
}
void WaveTableWindowBecomeActive(WaveTableWindowRec* Window)
{
OrdType XSize;
OrdType YSize;
CheckPtrExistence(Window);
if (Window->ActiveTextEdit != NIL)
{
EnableTextEditSelection(Window->ActiveTextEdit);
}
EnableScrollBar(Window->TableScroll);
XSize = GetWindowWidth(Window->ScreenID);
YSize = GetWindowHeight(Window->ScreenID);
SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
}
void WaveTableWindowBecomeInactive(WaveTableWindowRec* Window)
{
OrdType XSize;
OrdType YSize;
CheckPtrExistence(Window);
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
DisableScrollBar(Window->TableScroll);
XSize = GetWindowWidth(Window->ScreenID);
YSize = GetWindowHeight(Window->ScreenID);
SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
}
void WaveTableWindowJustResized(WaveTableWindowRec* Window)
{
OrdType XSize;
OrdType YSize;
CheckPtrExistence(Window);
XSize = GetWindowWidth(Window->ScreenID);
YSize = GetWindowHeight(Window->ScreenID);
SetClipRect(Window->ScreenID,0,0,XSize,YSize);
DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
SetTextEditPosition(Window->FunctionEdit,EXPRESSIONEDITX,EXPRESSIONEDITY(YSize),
EXPRESSIONEDITWIDTH(XSize),EXPRESSIONEDITHEIGHT);
SetScrollLocation(Window->TableScroll,WAVEFORMVIEWX,TABLESCROLLY(YSize),
WAVEFORMVIEWWIDTH(XSize));
}
static void WaveTableWindowScrollHook(long Parameter, ScrollType How,
WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
switch (How)
{
case eScrollToPosition:
Window->CurrentlyVisibleTable = Parameter;
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
break;
case eScrollPageMinus:
Window->CurrentlyVisibleTable -= PAGEINCREMENT;
if (Window->CurrentlyVisibleTable < 0)
{
Window->CurrentlyVisibleTable = 0;
}
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
break;
case eScrollPagePlus:
Window->CurrentlyVisibleTable += PAGEINCREMENT;
if (Window->CurrentlyVisibleTable > WaveTableWindowGetNumTables(Window) - 1)
{
Window->CurrentlyVisibleTable = WaveTableWindowGetNumTables(Window) - 1;
}
if (Window->CurrentlyVisibleTable < 0)
{
/* just in case there are 0 tables -- this makes index become -1 */
Window->CurrentlyVisibleTable = 0;
}
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
break;
case eScrollLineMinus:
Window->CurrentlyVisibleTable -= 1;
if (Window->CurrentlyVisibleTable < 0)
{
Window->CurrentlyVisibleTable = 0;
}
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
break;
case eScrollLinePlus:
Window->CurrentlyVisibleTable += 1;
if (Window->CurrentlyVisibleTable > WaveTableWindowGetNumTables(Window) - 1)
{
Window->CurrentlyVisibleTable = WaveTableWindowGetNumTables(Window) - 1;
}
if (Window->CurrentlyVisibleTable < 0)
{
/* just in case there are 0 tables -- this makes index become -1 */
Window->CurrentlyVisibleTable = 0;
}
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
break;
default:
EXECUTE(PRERR(AllowResume,"WaveTableWindowScrollHook: Unknown scroll opcode"));
break;
}
}
#define SOUNDBUFFERLENGTHBYTES (16384)
#define NUMSOUNDBUFFERS (4)
static void WaveTablePlayIt(WaveTableWindowRec* Window)
{
long NumTables;
long Scan;
SoundOutputNumBits SoundChannelBits;
largefixedsigned** ReferenceArray;
unsigned long WaveformIndex;
unsigned long WaveformIncrementor;
unsigned long WaveformMask;
long NumberOfIterationsAttack;
long NumberOfIterationsDecay;
long PlaybackSamplingRate;
void* OutputBuffer;
long OutputIndex;
/* get the number of tables */
NumTables = WaveTableStorDispNumTables(Window->WaveTableData);
/* fill in the buffer */
ReferenceArray = (largefixedsigned**)AllocPtrCanFail(sizeof(largefixedsigned*)
* NumTables,"WaveTablePlayIt: ReferenceArray");
if (ReferenceArray == NIL)
{
AlertHalt("There is not enough memory available to play the sample.",NIL);
FailurePoint1:
return;
}
for (Scan = 0; Scan < WaveTableStorDispNumTables(Window->WaveTableData); Scan += 1)
{
ReferenceArray[Scan] = WaveTableStorDispGetTable(Window->WaveTableData,Scan);
}
/* how many bits should be used for playback */
switch (WaveTableStorDispNumBits(Window->WaveTableData))
{
default:
EXECUTE(PRERR(ForceAbort,"WaveTablePlayIt: bad number of bits"));
break;
case eSample16bit:
SoundChannelBits = e16bit;
break;
case eSample8bit:
SoundChannelBits = e8bit;
break;
}
/* playback at what sampling rate */
PlaybackSamplingRate = WaveTableWindowGetTestSamplingRate(Window);
if (PlaybackSamplingRate < MINSAMPLINGRATE)
{
PlaybackSamplingRate = MINSAMPLINGRATE;
}
if (PlaybackSamplingRate > MAXSAMPLINGRATE)
{
PlaybackSamplingRate = MAXSAMPLINGRATE;
}
/* this is the initial index into the wave table */
WaveformIndex = 0;
/* this is the 16.16 bit fixed point number used to increment the index */
/* into the wave table */
WaveformIncrementor = WaveTableWindowGetNumFramesPerTable(Window)
* WaveTableWindowGetPitch(Window) / PlaybackSamplingRate * 65536;
/* this is used to mask off all garbage bits from the index when */
/* looking values up in the wave table */
WaveformMask = WaveTableWindowGetNumFramesPerTable(Window) - 1;
/* the number of times each wave slice has to be used */
NumberOfIterationsAttack = WaveTableWindowGetAscendingDuration(Window)
/ (double)NumTables * PlaybackSamplingRate;
NumberOfIterationsDecay = WaveTableWindowGetDescendingDuration(Window)
/ (double)NumTables * PlaybackSamplingRate;
if (!OpenSoundChannel(PlaybackSamplingRate,eMono,SoundChannelBits,
SOUNDBUFFERLENGTHBYTES,NUMSOUNDBUFFERS,NUMSOUNDBUFFERS))
{
AlertHalt("Unable top open the sound device.",NIL);
FailurePoint2:
ReleasePtr((char*)ReferenceArray);
goto FailurePoint1;
}
OutputIndex = 0;
do
{
OutputBuffer = CheckOutSoundBuffer();
} while (OutputBuffer == NIL);
if (SoundChannelBits == e16bit)
{
for (Scan = 0; Scan < NumTables; Scan += 1)
{
largefixedsigned* Buffer = ReferenceArray[Scan];
long Index;
for (Index = 0; Index < NumberOfIterationsAttack; Index += 1)
{
unsigned long SampleReference;
signed short Left;
signed short Right;
signed long Fraction;
SampleReference = (WaveformIndex >> 16) & WaveformMask;
Left = Buffer[SampleReference] >> SIXTEENBITSHIFTFACTOR;
Right = Buffer[SampleReference + 1] >> SIXTEENBITSHIFTFACTOR;
Fraction = (WaveformIndex & 0xffff) / 2;
WaveformIndex += WaveformIncrementor;
((short*)OutputBuffer)[OutputIndex] = (Left * (0x8000 - Fraction)
+ Right * Fraction) >> 15;
OutputIndex += 1;
if (OutputIndex >= SOUNDBUFFERLENGTHBYTES / sizeof(short))
{
SubmitBuffer((char*)OutputBuffer,SOUNDBUFFERLENGTHBYTES
/ sizeof(short),NIL,NIL);
if (RelinquishCPUJudiciouslyCheckCancel())
{
goto EscapePoint;
}
do
{
OutputBuffer = CheckOutSoundBuffer();
} while (OutputBuffer == NIL);
OutputIndex = 0;
}
}
}
}
else
{
for (Scan = 0; Scan < NumTables; Scan += 1)
{
largefixedsigned* Buffer = ReferenceArray[Scan];
long Index;
for (Index = 0; Index < NumberOfIterationsAttack; Index += 1)
{
unsigned long SampleReference;
signed short Left;
signed short Right;
signed long Fraction;
SampleReference = (WaveformIndex >> 16) & WaveformMask;
Left = Buffer[SampleReference] >> EIGHTBITSHIFTFACTOR;
Right = Buffer[SampleReference + 1] >> EIGHTBITSHIFTFACTOR;
Fraction = (WaveformIndex & 0xffff) / 2;
WaveformIndex += WaveformIncrementor;
((char*)OutputBuffer)[OutputIndex] = (Left * (0x8000 - Fraction)
+ Right * Fraction) >> 15;
OutputIndex += 1;
if (OutputIndex >= SOUNDBUFFERLENGTHBYTES / sizeof(char))
{
SubmitBuffer((char*)OutputBuffer,SOUNDBUFFERLENGTHBYTES
/ sizeof(char),NIL,NIL);
if (RelinquishCPUJudiciouslyCheckCancel())
{
goto EscapePoint;
}
do
{
OutputBuffer = CheckOutSoundBuffer();
} while (OutputBuffer == NIL);
OutputIndex = 0;
}
}
}
}
if (SoundChannelBits == e16bit)
{
for (Scan = NumTables - 1; Scan >= 0; Scan -= 1)
{
largefixedsigned* Buffer = ReferenceArray[Scan];
long Index;
for (Index = 0; Index < NumberOfIterationsDecay; Index += 1)
{
unsigned long SampleReference;
signed short Left;
signed short Right;
signed long Fraction;
SampleReference = (WaveformIndex >> 16) & WaveformMask;
Left = Buffer[SampleReference] >> SIXTEENBITSHIFTFACTOR;
Right = Buffer[SampleReference + 1] >> SIXTEENBITSHIFTFACTOR;
Fraction = (WaveformIndex & 0xffff) / 2;
WaveformIndex += WaveformIncrementor;
((short*)OutputBuffer)[OutputIndex] = (Left * (0x8000 - Fraction)
+ Right * Fraction) >> 15;
OutputIndex += 1;
if (OutputIndex >= SOUNDBUFFERLENGTHBYTES / sizeof(short))
{
SubmitBuffer((char*)OutputBuffer,SOUNDBUFFERLENGTHBYTES
/ sizeof(short),NIL,NIL);
if (RelinquishCPUJudiciouslyCheckCancel())
{
goto EscapePoint;
}
do
{
OutputBuffer = CheckOutSoundBuffer();
} while (OutputBuffer == NIL);
OutputIndex = 0;
}
}
}
SubmitBuffer((char*)OutputBuffer,OutputIndex / sizeof(short),NIL,NIL);
}
else
{
for (Scan = NumTables - 1; Scan >= 0; Scan -= 1)
{
largefixedsigned* Buffer = ReferenceArray[Scan];
long Index;
for (Index = 0; Index < NumberOfIterationsDecay; Index += 1)
{
unsigned long SampleReference;
signed short Left;
signed short Right;
signed long Fraction;
SampleReference = (WaveformIndex >> 16) & WaveformMask;
Left = Buffer[SampleReference] >> EIGHTBITSHIFTFACTOR;
Right = Buffer[SampleReference + 1] >> EIGHTBITSHIFTFACTOR;
Fraction = (WaveformIndex & 0xffff) / 2;
WaveformIndex += WaveformIncrementor;
((char*)OutputBuffer)[OutputIndex] = (Left * (0x8000 - Fraction)
+ Right * Fraction) >> 15;
OutputIndex += 1;
if (OutputIndex >= SOUNDBUFFERLENGTHBYTES / sizeof(char))
{
SubmitBuffer((char*)OutputBuffer,SOUNDBUFFERLENGTHBYTES
/ sizeof(char),NIL,NIL);
if (RelinquishCPUJudiciouslyCheckCancel())
{
goto EscapePoint;
}
do
{
OutputBuffer = CheckOutSoundBuffer();
} while (OutputBuffer == NIL);
OutputIndex = 0;
}
}
}
SubmitBuffer((char*)OutputBuffer,OutputIndex / sizeof(char),NIL,NIL);
}
EscapePoint:
CloseSoundChannel(NIL,NIL);
ReleasePtr((char*)ReferenceArray);
}
void WaveTableWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
ModifierFlags Modifiers, WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
&& (XLoc < GetWindowWidth(Window->ScreenID))
&& (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
&& (YLoc < GetWindowHeight(Window->ScreenID)))
{
UserGrowWindow(Window->ScreenID,XLoc,YLoc);
WaveTableWindowJustResized(Window);
}
else if (TextEditHitTest(Window->NameEdit,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->NameEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->NameEdit;
EnableTextEditSelection(Window->NameEdit);
}
TextEditDoMouseDown(Window->NameEdit,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->FunctionEdit,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->FunctionEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->FunctionEdit;
EnableTextEditSelection(Window->FunctionEdit);
}
TextEditDoMouseDown(Window->FunctionEdit,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->TestAttackDuration,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->TestAttackDuration)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->TestAttackDuration;
EnableTextEditSelection(Window->TestAttackDuration);
}
TextEditDoMouseDown(Window->TestAttackDuration,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->TestDecayDuration,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->TestDecayDuration)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->TestDecayDuration;
EnableTextEditSelection(Window->TestDecayDuration);
}
TextEditDoMouseDown(Window->TestDecayDuration,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->TestFrequency,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->TestFrequency)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->TestFrequency;
EnableTextEditSelection(Window->TestFrequency);
}
TextEditDoMouseDown(Window->TestFrequency,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->TestSamplingRate,XLoc,YLoc))
{
if (Window->ActiveTextEdit != Window->TestSamplingRate)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->TestSamplingRate;
EnableTextEditSelection(Window->TestSamplingRate);
}
TextEditDoMouseDown(Window->TestSamplingRate,XLoc,YLoc,Modifiers);
}
else if (TextEditHitTest(Window->NumFramesEdit,XLoc,YLoc))
{
WaveTableWindowSetNewNumFrames(Window);
}
else if (TextEditHitTest(Window->NumTablesEdit,XLoc,YLoc))
{
WaveTableWindowSetNewNumTables(Window);
}
else if (IconButtonHitTest(Window->Bits8Button,XLoc,YLoc))
{
if (IconButtonMouseDown(Window->Bits8Button,XLoc,YLoc,NIL,NIL))
{
SetWaveTableStorDispNumBits(Window->WaveTableData,eSample8bit);
SetIconButtonState(Window->Bits16Button,False);
Window->WaveDataModified = True;
}
}
else if (IconButtonHitTest(Window->Bits16Button,XLoc,YLoc))
{
if (IconButtonMouseDown(Window->Bits16Button,XLoc,YLoc,NIL,NIL))
{
SetWaveTableStorDispNumBits(Window->WaveTableData,eSample16bit);
SetIconButtonState(Window->Bits8Button,False);
Window->WaveDataModified = True;
}
}
else if (ScrollHitTest(Window->TableScroll,XLoc,YLoc))
{
ScrollHitProc(Window->TableScroll,CheckModifiers(),XLoc,YLoc,Window,
(void (*)(long,ScrollType,void*))&WaveTableWindowScrollHook);
}
else if (SimpleButtonHitTest(Window->TestButton,XLoc,YLoc))
{
if (SimpleButtonMouseDown(Window->TestButton,XLoc,YLoc,NIL,NIL))
{
WaveTablePlayIt(Window);
}
}
else
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
Window->ActiveTextEdit = NIL;
}
}
}
void WaveTableWindowDoKeyDown(unsigned char KeyCode,
ModifierFlags Modifiers, WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
if (Window->ActiveTextEdit != NIL)
{
TextEditDoKeyPressed(Window->ActiveTextEdit,KeyCode,Modifiers);
}
}
void WaveTableWindowClose(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
DisposeWaveTableWindow(Window);
}
void WaveTableWindowUpdator(WaveTableWindowRec* Window)
{
OrdType Height;
OrdType Width;
CheckPtrExistence(Window);
Width = GetWindowWidth(Window->ScreenID);
Height = GetWindowHeight(Window->ScreenID);
TextEditFullRedraw(Window->NameEdit);
TextEditFullRedraw(Window->FunctionEdit);
TextEditFullRedraw(Window->NumFramesEdit);
TextEditFullRedraw(Window->NumTablesEdit);
TextEditFullRedraw(Window->TestAttackDuration);
TextEditFullRedraw(Window->TestDecayDuration);
TextEditFullRedraw(Window->TestFrequency);
TextEditFullRedraw(Window->TestSamplingRate);
RedrawSimpleButton(Window->TestButton);
RedrawIconButton(Window->Bits8Button);
RedrawIconButton(Window->Bits16Button);
RedrawScrollBar(Window->TableScroll);
WaveTableWindowRedrawTable(Window);
SetClipRect(Window->ScreenID,0,0,Width,Height);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Name:",5,NAMEX,NAMEY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Frames:",7,FRAMEX,FRAMEY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Tables:",7,TABLESX,TABLESY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Test Attack:",12,
TESTATTACKX,TESTATTACKY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Test Decay:",11,
TESTDECAYX,TESTDECAYY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Test Freq:",10,
TESTFREQX,TESTFREQY,ePlain);
DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Test Smpl Rate:",15,
TESTSAMPLX,TESTSAMPLY,ePlain);
SetClipRect(Window->ScreenID,Width - 15,Height - 15,Width,Height);
DrawBitmap(Window->ScreenID,Width - 15,Height - 15,
GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
}
void WaveTableWindowMenuSetup(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
MainWindowEnableGlobalMenus(Window->MainWindow);
EnableMenuItem(mPaste);
ChangeItemName(mPaste,"Paste Text");
if (Window->ActiveTextEdit != NIL)
{
if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
{
EnableMenuItem(mCut);
ChangeItemName(mCut,"Cut Text");
EnableMenuItem(mCopy);
ChangeItemName(mCopy,"Copy Text");
EnableMenuItem(mClear);
ChangeItemName(mClear,"Clear Text");
}
EnableMenuItem(mSelectAll);
ChangeItemName(mSelectAll,"Select All Text");
if (TextEditCanWeUndo(Window->ActiveTextEdit))
{
EnableMenuItem(mUndo);
ChangeItemName(mUndo,"Undo Text Change");
}
}
else
{
if (Window->UndoBackupWaveTable != NIL)
{
EnableMenuItem(mUndo);
ChangeItemName(mUndo,"Undo Wave Table Edit");
}
}
EnableMenuItem(mCloseFile);
ChangeItemName(mCloseFile,"Close Wave Table Editor");
EnableMenuItem(mEvaluateCalc);
EnableMenuItem(mShiftLeft);
EnableMenuItem(mShiftRight);
EnableMenuItem(mBalanceParens);
ChangeItemName(mDeleteObject,"Delete Wave Table");
EnableMenuItem(mDeleteObject);
EnableMenuItem(mFind);
if (PtrSize(GlobalSearchString) != 0)
{
EnableMenuItem(mFindAgain);
if ((Window->ActiveTextEdit != NIL)
&& TextEditIsThereValidSelection(Window->ActiveTextEdit))
{
EnableMenuItem(mReplace);
EnableMenuItem(mReplaceAndFindAgain);
}
}
if ((Window->ActiveTextEdit != NIL)
&& TextEditIsThereValidSelection(Window->ActiveTextEdit))
{
EnableMenuItem(mEnterSelection);
}
SetItemCheckmark(Window->MyMenuItem);
}
void WaveTableWindowDoMenuCommand(WaveTableWindowRec* Window,
MenuItemType* MenuItem)
{
CheckPtrExistence(Window);
if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
{
}
else if (MenuItem == mPaste)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuPaste(Window->ActiveTextEdit);
}
}
else if (MenuItem == mCut)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuCut(Window->ActiveTextEdit);
}
}
else if (MenuItem == mCopy)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuCopy(Window->ActiveTextEdit);
}
}
else if (MenuItem == mClear)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuClear(Window->ActiveTextEdit);
}
}
else if (MenuItem == mSelectAll)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuSelectAll(Window->ActiveTextEdit);
}
}
else if (MenuItem == mUndo)
{
if (Window->ActiveTextEdit != NIL)
{
TextEditDoMenuUndo(Window->ActiveTextEdit);
}
else
{
WaveTableStorDispRec* Temp;
Temp = Window->UndoBackupWaveTable;
Window->UndoBackupWaveTable = Window->WaveTableData;
Window->WaveTableData = Temp;
Window->WaveDataModified = True;
WaveTableWindowUpdateAllParameters(Window);
}
}
else if (MenuItem == mCloseFile)
{
WaveTableWindowClose(Window);
}
else if (MenuItem == mEvaluateCalc)
{
WaveTableWindowEvaluateFunction(Window);
}
else if (MenuItem == mShiftLeft)
{
TextEditShiftSelectionLeftOneTab(Window->ActiveTextEdit);
}
else if (MenuItem == mShiftRight)
{
TextEditShiftSelectionRightOneTab(Window->ActiveTextEdit);
}
else if (MenuItem == mBalanceParens)
{
TextEditBalanceParens(Window->ActiveTextEdit);
}
else if (MenuItem == mDeleteObject)
{
WaveTableListDeleteWaveTable(Window->WaveTableList,Window->WaveTableObject);
}
else if (MenuItem == mFind)
{
if (Window->ActiveTextEdit != Window->FunctionEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->FunctionEdit;
EnableTextEditSelection(Window->ActiveTextEdit);
}
switch (DoFindDialog(&GlobalSearchString,&GlobalReplaceString,
mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
{
default:
EXECUTE(PRERR(ForceAbort,
"WaveTableWindowDoMenuCommand: bad value from DoFindDialog"));
break;
case eFindCancel:
case eDontFind:
break;
case eFindFromStart:
SetTextEditInsertionPoint(Window->ActiveTextEdit,0,0);
TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
TextEditShowSelection(Window->ActiveTextEdit);
break;
case eFindAgain:
TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
TextEditShowSelection(Window->ActiveTextEdit);
break;
}
}
else if (MenuItem == mFindAgain)
{
if (Window->ActiveTextEdit != Window->FunctionEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->FunctionEdit;
EnableTextEditSelection(Window->ActiveTextEdit);
}
TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
TextEditShowSelection(Window->ActiveTextEdit);
}
else if (MenuItem == mReplace)
{
if (Window->ActiveTextEdit != Window->FunctionEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->FunctionEdit;
EnableTextEditSelection(Window->ActiveTextEdit);
}
if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
{
TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
SYSTEMLINEFEED);
}
}
else if (MenuItem == mReplaceAndFindAgain)
{
if (Window->ActiveTextEdit != Window->FunctionEdit)
{
if (Window->ActiveTextEdit != NIL)
{
DisableTextEditSelection(Window->ActiveTextEdit);
}
Window->ActiveTextEdit = Window->FunctionEdit;
EnableTextEditSelection(Window->ActiveTextEdit);
}
if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
{
TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
SYSTEMLINEFEED);
TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
TextEditShowSelection(Window->ActiveTextEdit);
}
}
else if (MenuItem == mEnterSelection)
{
if (Window->ActiveTextEdit != NIL)
{
char* NewString;
NewString = TextEditGetSelection(Window->ActiveTextEdit);
if (NewString != NIL)
{
ReleasePtr(GlobalSearchString);
GlobalSearchString = NewString;
}
}
}
else
{
EXECUTE(PRERR(AllowResume,"WaveTableWindowDoMenuCommand: unknown menu command"));
}
}
/* get a copy of the wave table's name */
char* WaveTableWindowGetNameCopy(WaveTableWindowRec* Window)
{
char* TextCopy;
CheckPtrExistence(Window);
TextCopy = TextEditGetRawData(Window->NameEdit,"\x0a");
if (TextCopy != NIL)
{
SetTag(TextCopy,"WaveTableWindowNameCopy");
}
return TextCopy;
}
/* get a copy of the wave table's formula */
char* WaveTableWindowGetFormulaCopy(WaveTableWindowRec* Window)
{
char* TextCopy;
CheckPtrExistence(Window);
TextCopy = TextEditGetRawData(Window->FunctionEdit,"\x0a");
if (TextCopy != NIL)
{
SetTag(TextCopy,"WaveTableWindowFormulaCopy");
}
return TextCopy;
}
/* get the number of bits used for the wave table */
NumBitsType WaveTableWindowGetNumBits(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
if (GetIconButtonState(Window->Bits16Button))
{
return eSample16bit;
}
else
{
return eSample8bit;
}
}
/* get the number of periods in the wave table */
long WaveTableWindowGetNumTables(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
return WaveTableStorDispNumTables(Window->WaveTableData);
}
/* get the number of frames in each period of the wave table */
long WaveTableWindowGetNumFramesPerTable(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
return WaveTableStorDispNumFramesPerTable(Window->WaveTableData);
}
/* get the pitch at which the wave table should be tested */
double WaveTableWindowGetPitch(WaveTableWindowRec* Window)
{
char* Text;
double ReturnValue;
CheckPtrExistence(Window);
Text = TextEditGetRawData(Window->TestFrequency,SYSTEMLINEFEED);
if (Text != NIL)
{
ReturnValue = StringToLongDouble(Text,PtrSize(Text));
ReleasePtr(Text);
}
else
{
ReturnValue = 261.625565300598635;
}
return ReturnValue;
}
/* get the duration (seconds) for the increasing table index phase of the test */
double WaveTableWindowGetAscendingDuration(WaveTableWindowRec* Window)
{
char* Text;
double ReturnValue;
CheckPtrExistence(Window);
Text = TextEditGetRawData(Window->TestAttackDuration,SYSTEMLINEFEED);
if (Text != NIL)
{
ReturnValue = StringToLongDouble(Text,PtrSize(Text));
ReleasePtr(Text);
}
else
{
ReturnValue = 1;
}
return ReturnValue;
}
/* get the duration (seconds) for the decreasing table index phase of the test */
double WaveTableWindowGetDescendingDuration(WaveTableWindowRec* Window)
{
char* Text;
double ReturnValue;
CheckPtrExistence(Window);
Text = TextEditGetRawData(Window->TestDecayDuration,SYSTEMLINEFEED);
if (Text != NIL)
{
ReturnValue = StringToLongDouble(Text,PtrSize(Text));
ReleasePtr(Text);
}
else
{
ReturnValue = 2;
}
return ReturnValue;
}
/* get the sampling rate to use for the test */
long WaveTableWindowGetTestSamplingRate(WaveTableWindowRec* Window)
{
char* Text;
double ReturnValue;
CheckPtrExistence(Window);
Text = TextEditGetRawData(Window->TestSamplingRate,SYSTEMLINEFEED);
if (Text != NIL)
{
ReturnValue = StringToInteger(Text,PtrSize(Text));
ReleasePtr(Text);
}
else
{
ReturnValue = 44100;
}
return ReturnValue;
}
/* reset the scroll bar indices and redraw it */
void WaveTableWindowUpdateScrollBar(WaveTableWindowRec* Window)
{
CheckPtrExistence(Window);
SetMaxScrollIndex(Window->TableScroll,WaveTableWindowGetNumTables(Window));
SetScrollIndex(Window->TableScroll,Window->CurrentlyVisibleTable);
}
/* redraw the wave table waveform box */
void WaveTableWindowRedrawTable(WaveTableWindowRec* Window)
{
OrdType WindowWidth;
OrdType WindowHeight;
long Scan;
long Limit;
OrdType PreviousYValue;
OrdType PreviousXValue;
MyBoolean PreviousYValueIsValid;
CheckPtrExistence(Window);
WindowWidth = GetWindowWidth(Window->ScreenID);
WindowHeight = GetWindowHeight(Window->ScreenID);
SetClipRect(Window->ScreenID,WAVEFORMVIEWX,WAVEFORMVIEWY,
WAVEFORMVIEWWIDTH(WindowWidth),WAVEFORMVIEWHEIGHT(WindowHeight));
DrawBoxFrame(Window->ScreenID,eBlack,WAVEFORMVIEWX,WAVEFORMVIEWY,
WAVEFORMVIEWWIDTH(WindowWidth),WAVEFORMVIEWHEIGHT(WindowHeight));
if (WaveTableWindowGetNumTables(Window) == 0)
{
DrawBoxPaint(Window->ScreenID,eLightGrey,WAVEFORMVIEWX + 1,WAVEFORMVIEWY + 1,
WAVEFORMVIEWWIDTH(WindowWidth) - 2,WAVEFORMVIEWHEIGHT(WindowHeight) - 2);
return;
}
DrawBoxErase(Window->ScreenID,WAVEFORMVIEWX + 1,WAVEFORMVIEWY + 1,
WAVEFORMVIEWWIDTH(WindowWidth) - 2,WAVEFORMVIEWHEIGHT(WindowHeight) - 2);
ERROR((Window->CurrentlyVisibleTable < 0) || (Window->CurrentlyVisibleTable
>= WaveTableWindowGetNumTables(Window)),PRERR(ForceAbort,
"WaveTableWindowRedrawTable: current table index is out of range"));
Limit = WaveTableWindowGetNumFramesPerTable(Window);
PreviousYValueIsValid = False;
for (Scan = 0; Scan < Limit; Scan += 1)
{
double Value;
OrdType ThisYValue;
OrdType ThisXValue;
Value = largefixed2double(WaveTableStorDispGetFrame(Window->WaveTableData,
Window->CurrentlyVisibleTable,Scan));
ThisYValue = (1 - ((Value + 1) / 2)) * (WAVEFORMVIEWHEIGHT(WindowHeight) - 3)
+ WAVEFORMVIEWY + 1;
ThisXValue = (Scan * (WAVEFORMVIEWWIDTH(WindowWidth) - 2))
/ (Limit - 1) + WAVEFORMVIEWX + 1;
if (!PreviousYValueIsValid)
{
PreviousYValueIsValid = True;
PreviousYValue = ThisYValue;
PreviousXValue = ThisXValue;
}
DrawLine(Window->ScreenID,eBlack,PreviousXValue,PreviousYValue,
ThisXValue - PreviousXValue,ThisYValue - PreviousYValue);
PreviousYValue = ThisYValue;
PreviousXValue = ThisXValue;
}
}
/* the name of the file has changed, so change the title bar. the string is a */
/* non-null-terminated, and the caller is responsible for disposing of it */
void WaveTableWindowGlobalNameChange(WaveTableWindowRec* Window,
char* NewFilename)
{
char* LocalNameCopy;
CheckPtrExistence(Window);
CheckPtrExistence(NewFilename);
LocalNameCopy = WaveTableWindowGetNameCopy(Window);
if (LocalNameCopy != NIL)
{
char* SeparatorString;
SeparatorString = StringToBlockCopy(": ");
if (SeparatorString != NIL)
{
char* LeftHalfOfString;
LeftHalfOfString = ConcatBlockCopy(NewFilename,SeparatorString);
if (LeftHalfOfString != NIL)
{
char* TotalString;
TotalString = ConcatBlockCopy(LeftHalfOfString,LocalNameCopy);
if (TotalString != NIL)
{
char* NullTerminatedString;
NullTerminatedString = BlockToStringCopy(TotalString);
if (NullTerminatedString != NIL)
{
SetWindowName(Window->ScreenID,NullTerminatedString);
ChangeItemName(Window->MyMenuItem,NullTerminatedString);
ReleasePtr(NullTerminatedString);
}
ReleasePtr(TotalString);
}
ReleasePtr(LeftHalfOfString);
}
ReleasePtr(SeparatorString);
}
ReleasePtr(LocalNameCopy);
}
}
/* reset the title bar name even if the document name hasn't changed */
void WaveTableWindowResetTitlebar(WaveTableWindowRec* Window)
{
char* DocumentName;
CheckPtrExistence(Window);
DocumentName = GetCopyOfDocumentName(Window->MainWindow);
if (DocumentName != NIL)
{
WaveTableWindowGlobalNameChange(Window,DocumentName);
ReleasePtr(DocumentName);
}
}
/* set the number of periods to that stored in the edit box, and interpolate */
/* the periods. */
void WaveTableWindowSetNewNumTables(WaveTableWindowRec* Window)
{
long OriginalNumTables;
long NewNumTables;
CheckPtrExistence(Window);
OriginalNumTables = WaveTableWindowGetNumTables(Window);
NewNumTables = DoNumberDialog("Enter new number of tables:",OriginalNumTables,
mCut,mPaste,mCopy,mUndo,mSelectAll,mClear);
if (NewNumTables != OriginalNumTables)
{
WaveTableStorDispRec* NewTable;
long TableScan;
/* free up undo-backup info */
if (Window->UndoBackupWaveTable != NIL)
{
DisposeWaveTableStorDisp(Window->UndoBackupWaveTable);
Window->UndoBackupWaveTable = NIL;
}
/* build new table */
NewTable = NewWaveTableStorDisp(WaveTableStorDispNumBits(Window->WaveTableData),
WaveTableStorDispNumFramesPerTable(Window->WaveTableData));
if (NewTable == NIL)
{
MemoryFailurePoint1:
AlertHalt("There is not enough memory available to resize the wave table.",NIL);
return;
}
for (TableScan = 0; TableScan < NewNumTables; TableScan += 1)
{
if (!WaveTableStorDispAppendEntry(NewTable))
{
MemoryFailurePoint2:
DisposeWaveTableStorDisp(NewTable);
goto MemoryFailurePoint1;
}
}
if ((NewNumTables != 0) && (OriginalNumTables != 0))
{
long NumFrames;
NumFrames = WaveTableStorDispNumFramesPerTable(NewTable);
/* store the neat things into the table. we use linear interpolation */
/* between adjacent tables to create new tables. */
for (TableScan = 0; TableScan < NewNumTables; TableScan += 1)
{
double LeftWeight;
double RightWeight;
long LeftIndex;
long RightIndex;
double PrecisePositioning;
long FrameScan;
if (NewNumTables > 1)
{
PrecisePositioning = (double)TableScan / (double)(NewNumTables - 1)
* (double)(OriginalNumTables - 1);
}
else
{
PrecisePositioning = (double)(OriginalNumTables - 1) / 2;
}
LeftIndex = (long)PrecisePositioning;
RightIndex = LeftIndex + 1;
RightWeight = PrecisePositioning - LeftIndex;
LeftWeight = 1 - RightWeight;
for (FrameScan = 0; FrameScan < NumFrames; FrameScan += 1)
{
double LeftValue;
double RightValue;
double ResultantComposite;
LeftValue = largefixed2double(WaveTableStorDispGetFrame(
Window->WaveTableData,LeftIndex,FrameScan));
if (RightIndex < OriginalNumTables)
{
RightValue = largefixed2double(WaveTableStorDispGetFrame(
Window->WaveTableData,RightIndex,FrameScan));
}
else
{
RightValue = 0;
ERROR(RightWeight != 0,PRERR(ForceAbort,
"WaveTableWindowSetNewNumTables: on last table, but right "
"weight is non-zero."));
}
ResultantComposite = LeftValue * LeftWeight
+ RightValue * RightWeight;
WaveTableStorDispSetFrame(NewTable,TableScan,FrameScan,
double2largefixed(ResultantComposite));
}
}
}
/* save it */
Window->UndoBackupWaveTable = Window->WaveTableData;
Window->WaveTableData = NewTable;
WaveTableWindowUpdateAllParameters(Window);
Window->WaveDataModified = True;
}
}
/* set the number of periods edit box to be the same as the data */
void WaveTableWindowUpdateTableCountEdit(WaveTableWindowRec* Window)
{
char* StringTemp;
CheckPtrExistence(Window);
StringTemp = IntegerToString(WaveTableObjectGetNumTables(Window->WaveTableObject));
if (StringTemp == NIL)
{
return;
}
TextEditNewRawData(Window->NumTablesEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->NumTablesEdit);
}
/* set the number of frames edit box to be the same as the data */
void WaveTableWindowUpdateFrameCountEdit(WaveTableWindowRec* Window)
{
char* StringTemp;
CheckPtrExistence(Window);
StringTemp = IntegerToString(
WaveTableStorDispNumFramesPerTable(Window->WaveTableData));
if (StringTemp == NIL)
{
return;
}
TextEditNewRawData(Window->NumFramesEdit,StringTemp,"\x0a");
ReleasePtr(StringTemp);
TextEditHasBeenSaved(Window->NumFramesEdit);
}
/* set all edit boxes to be the same as the underlying data */
void WaveTableWindowUpdateAllParameters(WaveTableWindowRec* Window)
{
if (Window->CurrentlyVisibleTable
> WaveTableObjectGetNumTables(Window->WaveTableObject) - 1)
{
Window->CurrentlyVisibleTable
= WaveTableObjectGetNumTables(Window->WaveTableObject) - 1;
}
if (Window->CurrentlyVisibleTable < 0)
{
Window->CurrentlyVisibleTable = 0;
}
WaveTableWindowUpdateTableCountEdit(Window);
WaveTableWindowUpdateFrameCountEdit(Window);
WaveTableWindowUpdateScrollBar(Window);
WaveTableWindowRedrawTable(Window);
}
/* give a dialog box asking for a new number of frames, and then interpolate all */
/* of the wave periods. */
void WaveTableWindowSetNewNumFrames(WaveTableWindowRec* Window)
{
long OriginalNumFrames;
long NewNumFrames;
WaveTableStorDispRec* NewTable;
long NumberOfTables;
long TableScan;
CheckPtrExistence(Window);
OriginalNumFrames = WaveTableStorDispNumFramesPerTable(Window->WaveTableData);
NewNumFrames = AskForNewWaveTableSize(OriginalNumFrames);
if (NewNumFrames == OriginalNumFrames)
{
return;
}
/* dump the undo backup information */
if (Window->UndoBackupWaveTable != NIL)
{
DisposeWaveTableStorDisp(Window->UndoBackupWaveTable);
Window->UndoBackupWaveTable = NIL;
}
/* create a new table */
NewTable = NewWaveTableStorDisp(WaveTableStorDispNumBits(Window->WaveTableData),
NewNumFrames);
if (NewTable == NIL)
{
MemoryFailurePoint1:
AlertHalt("There is not enough memory available to resample the wave table.",NIL);
return;
}
NumberOfTables = WaveTableStorDispNumTables(Window->WaveTableData);
for (TableScan = 0; TableScan < NumberOfTables; TableScan += 1)
{
if (!WaveTableStorDispAppendEntry(NewTable))
{
MemoryFailurePoint2:
DisposeWaveTableStorDisp(NewTable);
goto MemoryFailurePoint1;
}
}
/* this one handles interpolating between entries to expand the table */
if (NewNumFrames > OriginalNumFrames)
{
long ExpansionFactor;
ExpansionFactor = NewNumFrames / OriginalNumFrames;
for (TableScan = 0; TableScan < NumberOfTables; TableScan += 1)
{
long NewFrameScan;
for (NewFrameScan = 0; NewFrameScan < NewNumFrames; NewFrameScan += 1)
{
double LeftWeight;
double RightWeight;
long LeftIndex;
long RightIndex;
double PrecisePositioning;
double LeftValue;
double RightValue;
double ResultantComposite;
PrecisePositioning = (double)NewFrameScan / (double)NewNumFrames
* (double)OriginalNumFrames;
LeftIndex = (long)PrecisePositioning;
RightIndex = LeftIndex + 1;
RightWeight = PrecisePositioning - LeftIndex;
LeftWeight = 1 - RightWeight;
LeftValue = largefixed2double(WaveTableStorDispGetFrame(
Window->WaveTableData,TableScan,LeftIndex));
RightValue = largefixed2double(WaveTableStorDispGetFrame(
Window->WaveTableData,TableScan,RightIndex % OriginalNumFrames));
ResultantComposite = LeftValue * LeftWeight
+ RightValue * RightWeight;
WaveTableStorDispSetFrame(NewTable,TableScan,NewFrameScan,
double2largefixed(ResultantComposite));
}
}
}
/* this one handles averaging the frames for table compression */
else
{
long FoldingFactor;
FoldingFactor = OriginalNumFrames / NewNumFrames;
for (TableScan = 0; TableScan < NumberOfTables; TableScan += 1)
{
long NewFrameScan;
for (NewFrameScan = 0; NewFrameScan < NewNumFrames; NewFrameScan += 1)
{
double Accumulator;
long SumScan;
double Average;
Accumulator = 0;
for (SumScan = 0; SumScan < FoldingFactor; SumScan += 1)
{
Accumulator += largefixed2double(WaveTableStorDispGetFrame(
Window->WaveTableData,TableScan,
NewFrameScan * FoldingFactor + SumScan));
}
Average = Accumulator / FoldingFactor;
WaveTableStorDispSetFrame(NewTable,TableScan,NewFrameScan,
double2largefixed(Average));
}
}
}
Window->UndoBackupWaveTable = Window->WaveTableData;
Window->WaveTableData = NewTable;
WaveTableWindowUpdateAllParameters(Window);
Window->WaveDataModified = True;
}
/* argument list for wave table function thang */
static FunctionParamRec ArgumentList[] =
{
{"frames",eInteger},
{"tables",eInteger},
{"data",eArrayOfFixed}
};
#define ARGLISTLENGTH (sizeof(ArgumentList) / sizeof(ArgumentList[0]))
/* evaluate the wave formula and update the wave data */
void WaveTableWindowEvaluateFunction(WaveTableWindowRec* Window)
{
char* Blob;
PcodeRec* FuncCode;
CompileErrors Error;
long LineNumber;
ParamStackRec* ParamList;
EvalErrors OtherError;
OpcodeRec* ErrorOpcode;
long OffendingInstruction;
DataTypes ReturnType;
long TotalFramesPerTable;
long TotalNumTables;
CheckPtrExistence(Window);
/* bring the world up to date */
if (!MainWindowMakeUpToDateFunctions(Window->MainWindow))
{
return;
}
/* prepare the text blob to be evaluated */
Blob = TextEditGetRawData(Window->FunctionEdit,"\x0a");
if (Blob == NIL)
{
FailurePoint1:
AlertHalt("There is not enough memory available to compile the expression.",NIL);
return;
}
if (Window->UndoBackupWaveTable != NIL)
{
DisposeWaveTableStorDisp(Window->UndoBackupWaveTable);
Window->UndoBackupWaveTable = NIL;
}
/* perform compilation */
Error = CompileSpecialFunction(ArgumentList,ARGLISTLENGTH,&LineNumber,
&ReturnType,Blob,&FuncCode);
ReleasePtr(Blob);
if (Error != eCompileNoError)
{
SetTextEditSelection(Window->FunctionEdit,LineNumber - 1,0,LineNumber,0);
TextEditShowSelection(Window->FunctionEdit);
AlertHalt("A compile error occurred: _",GetCompileErrorString(Error));
return;
}
/* try to evaluate the code */
ParamList = NewParamStack();
if (ParamList == NIL)
{
SecondFailurePoint1:
DisposePcode(FuncCode);
AlertHalt("There is not enough memory available to evaluate the expression.",NIL);
return;
}
TotalFramesPerTable = WaveTableWindowGetNumFramesPerTable(Window);
TotalNumTables = WaveTableWindowGetNumTables(Window);
/* add a space for the return value */
if (!AddIntegerToStack(ParamList,0))
{
SecondFailurePoint2:
DisposeParamStack(ParamList);
goto SecondFailurePoint1;
}
/* frames */
if (!AddIntegerToStack(ParamList,TotalFramesPerTable))
{
goto SecondFailurePoint2;
}
/* tables */
if (!AddIntegerToStack(ParamList,TotalNumTables))
{
goto SecondFailurePoint2;
}
/* data */
{
largefixedsigned* TheDataBlock;
long TableScan;
long FrameScan;
TheDataBlock = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
* TotalFramesPerTable * TotalNumTables,"WaveTableWindowEvaluateFunction: array");
if (TheDataBlock == NIL)
{
goto SecondFailurePoint2;
}
for (TableScan = 0; TableScan < TotalNumTables; TableScan += 1)
{
for (FrameScan = 0; FrameScan < TotalFramesPerTable; FrameScan += 1)
{
PRNGCHK(TheDataBlock,&(TheDataBlock[TableScan * TotalFramesPerTable
+ FrameScan]),sizeof(TheDataBlock[TableScan * TotalFramesPerTable
+ FrameScan]));
TheDataBlock[TableScan * TotalFramesPerTable + FrameScan]
= WaveTableStorDispGetFrame(Window->WaveTableData,TableScan,FrameScan);
}
}
if (!AddArrayToStack(ParamList,TheDataBlock))
{
ReleasePtr((char*)TheDataBlock);
goto SecondFailurePoint2;
}
}
/* executing the actual code */
OtherError = EvaluatePcode(ParamList,FuncCode,
Window->CodeCenter,&ErrorOpcode,&OffendingInstruction,Window->MainWindow,
(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleLeftCopy,
(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleRightCopy,
(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleMonoCopy,
(SampleErrors (*)(void*,char*,long*))&MainWindowGetWaveTableFrameCount,
(SampleErrors (*)(void*,char*,long*))&MainWindowGetWaveTableTableCount,
(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetWaveTableArray,
Window->MainWindow,
(struct InteractionWindowRec* (*)(void*))&MainWindowGetInteractionWindow);
if (OtherError != eEvalNoError)
{
char* FuncNameString;
FuncCodeRec* ErrorFunction;
MyBoolean SuccessFlag;
/* present error message */
SuccessFlag = False;
ErrorFunction = GetFunctionFromOpcode(Window->CodeCenter,ErrorOpcode);
if (ErrorFunction == NIL)
{
FuncNameString = StringToBlockCopy("<anonymous>");
}
else
{
FuncNameString = CopyPtr(GetFunctionName(ErrorFunction));
}
if (FuncNameString != NIL)
{
char* Key;
Key = StringToBlockCopy("_");
if (Key != NIL)
{
char* BaseMessage;
BaseMessage = StringFromRaw("Error in function _, instruction _: _");
if (BaseMessage != NIL)
{
char* FixedMessage1;
FixedMessage1 = ReplaceBlockCopy(BaseMessage,Key,FuncNameString);
if (FixedMessage1 != NIL)
{
char* NumberStr;
NumberStr = IntegerToString(OffendingInstruction);
if (NumberStr != NIL)
{
char* FixedMessage2;
FixedMessage2 = ReplaceBlockCopy(FixedMessage1,Key,NumberStr);
if (FixedMessage2 != NIL)
{
AlertHalt(FixedMessage2,GetPcodeErrorMessage(OtherError));
SuccessFlag = True;
ReleasePtr(FixedMessage2);
}
ReleasePtr(NumberStr);
}
ReleasePtr(FixedMessage1);
}
ReleasePtr(BaseMessage);
}
ReleasePtr(Key);
}
ReleasePtr(FuncNameString);
}
if (!SuccessFlag)
{
AlertHalt("There is not enough memory available to show "
"the compile error message.",NIL);
}
DisposeParamStack(ParamList);
DisposePcode(FuncCode);
return;
}
/* get the data out */
{
largefixedsigned* DataBlock;
WaveTableStorDispRec* NewWaveTable;
long TableScan;
long FrameScan;
DataBlock = (largefixedsigned*)GetStackArray(ParamList,3);
CheckPtrExistence((char*)DataBlock);
NewWaveTable = NewWaveTableStorDisp(WaveTableStorDispNumBits(
Window->WaveTableData),TotalFramesPerTable);
if (NewWaveTable == NIL)
{
FinishedSideNoMemory1:
AlertHalt("There is not enough memory available to build the wave.",NIL);
DisposeParamStack(ParamList);
DisposePcode(FuncCode);
return;
}
for (TableScan = 0; TableScan < TotalNumTables; TableScan += 1)
{
if (!WaveTableStorDispAppendEntry(NewWaveTable))
{
FinishedSideNoMemory2:
DisposeWaveTableStorDisp(NewWaveTable);
goto FinishedSideNoMemory1;
}
}
for (TableScan = 0; TableScan < TotalNumTables; TableScan += 1)
{
for (FrameScan = 0; FrameScan < TotalFramesPerTable; FrameScan += 1)
{
PRNGCHK(DataBlock,&(DataBlock[TableScan * TotalFramesPerTable + FrameScan]),
sizeof(DataBlock[TableScan * TotalFramesPerTable + FrameScan]));
WaveTableStorDispSetFrame(NewWaveTable,TableScan,FrameScan,
DataBlock[TableScan * TotalFramesPerTable + FrameScan]);
}
}
Window->UndoBackupWaveTable = Window->WaveTableData;
Window->WaveTableData = NewWaveTable;
Window->WaveDataModified = True;
}
DisposeParamStack(ParamList); /* disposes our array for us */
DisposePcode(FuncCode);
WaveTableWindowUpdateAllParameters(Window);
}
/* get a copy of the wave data array */
largefixedsigned* WaveTableWindowGetWaveArray(WaveTableWindowRec* Window)
{
largefixedsigned* Array;
long TableLimit;
long FrameLimit;
long TableScan;
CheckPtrExistence(Window);
TableLimit = WaveTableStorDispNumTables(Window->WaveTableData);
FrameLimit = WaveTableStorDispNumFramesPerTable(Window->WaveTableData);
Array = (largefixedsigned*)AllocPtrCanFail(TableLimit * FrameLimit
* sizeof(largefixedsigned),"WaveTableWindowGetWaveArray");
if (Array != NIL)
{
for (TableScan = 0; TableScan < TableLimit; TableScan += 1)
{
long FrameScan;
for (FrameScan = 0; FrameScan < FrameLimit; FrameScan += 1)
{
PRNGCHK(Array,&(Array[TableScan * FrameLimit + FrameScan]),
sizeof(Array[TableScan * FrameLimit + FrameScan]));
Array[TableScan * FrameLimit + FrameScan]
= WaveTableStorDispGetFrame(Window->WaveTableData,
TableScan,FrameScan);
}
}
}
return Array;
}
/* force the wave data to be written back to the object. this does not write back */
/* any other data. */
MyBoolean WaveTableWindowForceWaveTableUpdate(WaveTableWindowRec* Window)
{
WaveTableStorageRec* NewWaveTable;
CheckPtrExistence(Window);
NewWaveTable = NewWaveTableStorage(WaveTableStorDispNumBits(Window->WaveTableData),
WaveTableStorDispNumFramesPerTable(Window->WaveTableData));
if (NewWaveTable != NIL)
{
long Limit;
long Scan;
Limit = WaveTableStorDispNumTables(Window->WaveTableData);
for (Scan = 0; Scan < Limit; Scan += 1)
{
long Index;
long IndexLimit;
if (!WaveTableStorageAppendEntry(NewWaveTable))
{
DisposeWaveTableStorage(NewWaveTable);
return False;
}
IndexLimit = WaveTableStorDispNumFramesPerTable(Window->WaveTableData);
for (Index = 0; Index < IndexLimit; Index += 1)
{
WaveTableStorageSetFrame(NewWaveTable,Scan,Index,
WaveTableStorDispGetFrame(Window->WaveTableData,Scan,Index));
}
}
WaveTableObjectPutNewData(Window->WaveTableObject,NewWaveTable);
return True;
}
else
{
return False;
}
}
/* force all data to be written back to the object. this includes calling */
/* WaveTableWindowForceWaveTableUpdate() */
MyBoolean WaveTableWindowWritebackModifiedData(WaveTableWindowRec* Window)
{
MyBoolean SuccessFlag = True;
CheckPtrExistence(Window);
if (TextEditDoesItNeedToBeSaved(Window->NameEdit))
{
char* String;
String = WaveTableWindowGetNameCopy(Window);
if (String != NIL)
{
WaveTableObjectNewName(Window->WaveTableObject,String);
TextEditHasBeenSaved(Window->NameEdit);
}
else
{
SuccessFlag = False;
}
}
if (TextEditDoesItNeedToBeSaved(Window->FunctionEdit))
{
char* String;
String = WaveTableWindowGetFormulaCopy(Window);
if (String != NIL)
{
WaveTableObjectNewFormula(Window->WaveTableObject,String);
TextEditHasBeenSaved(Window->FunctionEdit);
}
else
{
SuccessFlag = False;
}
}
if (TextEditDoesItNeedToBeSaved(Window->TestAttackDuration))
{
char* String;
String = TextEditGetRawData(Window->TestAttackDuration,SYSTEMLINEFEED);
if (String != NIL)
{
SetWaveTableObjectTestAttack(Window->WaveTableObject,
StringToLongDouble(String,PtrSize(String)));
ReleasePtr(String);
TextEditHasBeenSaved(Window->TestAttackDuration);
}
else
{
SuccessFlag = False;
}
}
if (TextEditDoesItNeedToBeSaved(Window->TestDecayDuration))
{
char* String;
String = TextEditGetRawData(Window->TestDecayDuration,SYSTEMLINEFEED);
if (String != NIL)
{
SetWaveTableObjectTestDecay(Window->WaveTableObject,
StringToLongDouble(String,PtrSize(String)));
ReleasePtr(String);
TextEditHasBeenSaved(Window->TestDecayDuration);
}
else
{
SuccessFlag = False;
}
}
if (TextEditDoesItNeedToBeSaved(Window->TestFrequency))
{
char* String;
String = TextEditGetRawData(Window->TestFrequency,SYSTEMLINEFEED);
if (String != NIL)
{
SetWaveTableObjectTestPitch(Window->WaveTableObject,
StringToLongDouble(String,PtrSize(String)));
ReleasePtr(String);
TextEditHasBeenSaved(Window->TestFrequency);
}
else
{
SuccessFlag = False;
}
}
if (TextEditDoesItNeedToBeSaved(Window->TestSamplingRate))
{
char* String;
String = TextEditGetRawData(Window->TestSamplingRate,SYSTEMLINEFEED);
if (String != NIL)
{
SetWaveTableObjectTestSamplingRate(Window->WaveTableObject,
StringToInteger(String,PtrSize(String)));
ReleasePtr(String);
TextEditHasBeenSaved(Window->TestSamplingRate);
}
else
{
SuccessFlag = False;
}
}
if (Window->WaveDataModified)
{
if (WaveTableWindowForceWaveTableUpdate(Window))
{
Window->WaveDataModified = False;
}
else
{
SuccessFlag = False;
}
}
return SuccessFlag;
}